package com.ruoyi.file.service;

import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import io.minio.GetObjectArgs;
import io.minio.errors.ErrorResponseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.nacos.common.utils.IoUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.file.config.MinioConfig;
import com.ruoyi.file.utils.FileUploadUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;

import javax.servlet.http.HttpServletResponse;



/**
 * Minio 文件存储
 *
 * @author ruoyi
 */
@Service
@Primary
public class MinioSysFileServiceImpl implements ISysFileService
{
    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;

    /**
     * Minio文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception
    {
        InputStream inputStream = null;
        try
        {
            String fileName = FileUploadUtils.extractFilename(file);
            inputStream = file.getInputStream();
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            client.putObject(args);
            return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
        }
        catch (Exception e)
        {
            throw new RuntimeException("Minio上传文件失败", e);
        }
        finally
        {
            IoUtils.closeQuietly(inputStream);
        }
    }

    /**
     * Minio文件删除接口
     * 
     * @param fileUrl 文件访问URL
     * @throws Exception
     */
    @Override
    public void deleteFile(String fileUrl) throws Exception
    {
        try
        {
            String minioFile = StringUtils.substringAfter(fileUrl, minioConfig.getBucketName());
            client.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(minioFile).build());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Minio Failed to delete file", e);
        }
    }

    @Override
    public void downloadFile(String objectName, HttpServletResponse response) throws Exception {
        try {
            // 1. URL解码（处理中文/特殊字符编码）
            String fileName = URLDecoder.decode(objectName, "UTF-8");

            // 2. 去除可能的路径前缀（确保只保留文件名）
            if (fileName.startsWith("/")) {
                fileName = fileName.substring(1);
            }
            if (fileName.startsWith(minioConfig.getBucketName() + "/")) {
                fileName = fileName.substring(minioConfig.getBucketName().length() + 1);
            }

            // 3. 获取文件流（使用解码后的正确文件名）
            try (InputStream in = client.getObject(
                    GetObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(fileName)
                            .build())) {

                // 4. 设置响应头 - 关键修改部分
                response.setContentType("application/octet-stream");

                // 处理不同浏览器的中文文件名兼容问题
                String userAgent = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getRequest().getHeader("User-Agent");

                String encodedFileName;
                if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                    // IE浏览器
                    encodedFileName = URLEncoder.encode(fileName, "UTF-8");
                } else if (userAgent.contains("Mozilla")) {
                    // Firefox, Chrome等现代浏览器
                    encodedFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
                } else {
                    // 其他浏览器
                    encodedFileName = URLEncoder.encode(fileName, "UTF-8");
                }

                // 设置Content-Disposition头
                response.setHeader("Content-Disposition",
                        "attachment; filename=\"" + encodedFileName + "\"");

                // 5. 写入响应流
                IoUtils.copy(in, response.getOutputStream());
                response.flushBuffer();
            }
        } catch (Exception e) {
            throw new RuntimeException("下载文件失败: " + e.getMessage(), e);
        }
    }


}
